package com.vimi8.ebb.auth.configuration;


import com.vimi8.ebb.auth.model.DBUserDetails;
import com.vimi8.ebb.auth.service.DBUserDetailsService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.authentication.*;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

import java.util.Set;

/**
 * 用户是身份认证
 */
public class AuthenticationProviderImpl implements AuthenticationProvider {
    private Logger logger =  LoggerFactory.getLogger(this.getClass());


    private DBUserDetailsService dbUserDetailsService;

    public AuthenticationProviderImpl(DBUserDetailsService dbUserDetailsService){
        this.dbUserDetailsService=dbUserDetailsService;
    }
    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {


        UsernamePasswordAuthenticationToken token = (UsernamePasswordAuthenticationToken) authentication;
        String loginName= token.getName();
        String loginPassword=String.valueOf(token.getCredentials());
        DBUserDetails user = null;
        try {
            user = dbUserDetailsService.getUserDetailsByPhoneNumber(loginName);
        }catch (Exception ex){
            logger.error(ex.getLocalizedMessage());
        }
        if(user==null){
            try {
                user = dbUserDetailsService.getUserDetailsByIdCard(loginName);
            }catch (Exception ex){
                logger.error(ex.getLocalizedMessage());
            }
        }
        if(user==null){
            try {
                user = dbUserDetailsService.getUserDetailsByUsername(loginName);
            }catch (Exception ex){
                logger.error(ex.getLocalizedMessage());
            }
        }
        if(user==null){
            throw new UsernameNotFoundException("invalid username or password");
        }
        if(!user.isAccountNonExpired()){
            throw new AccountExpiredException("invalid username or password");
        }
        if(!user.isAccountNonLocked() ){
            throw new LockedException("invalid username or password");
        }
        if( !user.isEnabled() ){
            throw new DisabledException("invalid username or password");
        }
        if(!user.isCredentialsNonExpired()){
            throw new CredentialsExpiredException("invalid username or password");
        }


        Set<GrantedAuthority> authorities = null;

        if(user.getAuthCode()!=null && user.getAuthCode().equals(loginPassword)){
            //此次如果使用手机号+验证码登录,则需要更新验证码状态为已使用,防止被二次使用
           dbUserDetailsService.updateUserDetailsForAuthCodeIsUsed(user.getUsername());
            //此处可做一些记录,如最后登录时间,登录IP等((WebAuthenticationDetails)token.getDetails()).getRemoteAddress(),也可更外层做;
            //验证成功setAuthenticated(true)
            return new UsernamePasswordAuthenticationToken(user.getUsername(),user.getAuthCode(),authorities);
        }
        //继续尝试 用密码登陆
        if(user.getPassword()!=null && user.getPassword().equals(loginPassword)){
            //此处可做一些记录,如最后登录时间,登录IP等((WebAuthenticationDetails)token.getDetails()).getRemoteAddress(),也可更外层做;
            //验证成功setAuthenticated(true)
            return new UsernamePasswordAuthenticationToken(user.getUsername(),user.getPassword(),authorities);
        } else{
            //验证失败setAuthenticated(false)
            return new UsernamePasswordAuthenticationToken(user.getUsername(),user.getAuthCode()!=null?user.getAuthCode():user.getPassword());
        }
    }

    @Override
    public boolean supports(Class<?> aClass) {
        //返回true后才会执行上面的authenticate方法,这步能确保authentication能正确转换类型
        //return UsernamePasswordAuthenticationToken.class.equals(aClass);
        return (UsernamePasswordAuthenticationToken.class.isAssignableFrom(aClass));
    }
}